clear all
*cap log close
set more off
set seed 603


* relationship between stringency and stop volume -------------------------------------------

* compute stop frequencies ---------
use "${data}/out/2-stopsfhp", clear
drop if mi(officerid)
gen ym   = (year*100)+month
gen Nany = 1 
gen Nspd = (viol_code==575)

collapse (sum) Nany Nspd, by(officerid ym) fast
summ Nany if Nany>0
local MUany = r(mean)
summ Nspd if Nspd>0
local MUspd = r(mean)

use "${data}/out/2-stopsfhp", clear
drop if mi(officerid)
gen  ym    = (year*100)+month
egen totfe = group(countynum year month wknd shift)

gen Nany = 1
gen Nspd = (viol_code==575)
collapse (sum) Nany Nspd, by(officerid ym totfe) fast

bysort totfe: egen Nanytot = sum(Nany)
bysort totfe: egen Nanyspd = sum(Nspd)

bysort totfe: egen muNany = mean(Nany)
bysort totfe: egen muNspd = mean(Nspd)
gen residNany = Nany - muNany 
gen residNspd = Nspd - muNspd 
collapse (mean) residNany residNspd, by(officerid) fast
tempfile temp
save    `temp'

* merge with stringency info ------------
use "${data}/out/4-main", clear
reghdfe Z, absorb(totfe) nocons resid
predict rZ, resid
gen Nall = 1 
collapse (mean) rZ (sum) Nall, by(officerid)
merge 1:1 officerid using `temp', keep(3) nogen

* setup for plot -------------------------
reg residNany rZ, r
local bprint1 = "{it:{&beta}} = `:di %4.3f _b[rZ]' (`:di %4.3f _se[rZ]')"
reg residNspd rZ, r
local bprint2 = "{it:{&beta}} = `:di %4.3f _b[rZ]' (`:di %4.3f _se[rZ]')"

binscatter residNany rZ, nq(20) nodraw gen(BIN)
*gcollapse (mean) residN* rZ, by(BIN)
collapse (mean) residN* rZ, by(BIN)
replace residNany = residNany + `MUany'
replace residNspd = residNspd + `MUspd'

* build plot ------------------------------
#delimit ;
scatter residNany rZ, mcolor(dknavy) msymbol(Oh)    || 
lfit    residNany rZ, lcolor(dknavy) lpattern(dash) ||
scatter residNspd rZ, lcolor(dkgreen) msymbol(Dh)   ||
lfit    residNspd rZ, lcolor(dkgreen) lpattern(dash)
graphregion(color(white)) plotregion(lcolor(black) lwidth(medthin))
ylab(10(10)60,nogrid) xlab(-0.5(0.25)0.5,nogrid)
legend(ring(0) pos(11) cols(1) order(1 3) region(lstyle(border))
lab(1 "All Citations") lab(3 "Speeding Citations"))
xtitle("Officer Stringency") ytitle("Adjusted Monthly Citations")
text(40 0.33 "`bprint1'", place(n))
text(28 0.33 "`bprint2'", place(s)) ;
#delimit cr 
graph export "${out}/main/validity_frequency.pdf", replace
* -------------------------------------------------------------------------------------------


* relationship between stringency and predicted/past offending ------------------------------

* macros for plotting (outcome/axes) -------
local ylo = 0.34
local yhi = 0.365
local yst = 0.005
local yt1 = 0.360
local yt2 = 0.345
local Y   = "cite"

* setup data with relevant outcomes ---------
use "${data}/out/4-main", clear
local Y = "cite"
gen  Y1 = hatho_`Y'
gen  Y2 = `Y'_py1

* store regressions and means ---------------
reghdfe Y1 Z, absorb(totfe) vce(cluster officerid)
local b1 = "{it:{&beta}} = `:di %6.5f _b[Z]' (`:di %5.4f _se[Z]')"
reghdfe Y2 Z, absorb(totfe) vce(cluster officerid)
local b2 = "{it:{&beta}} = `:di %6.5f _b[Z]' (`:di %5.4f _se[Z]')"

summ Y1 
local mu1 = r(mean)
summ Y2 
local mu2 = r(mean)

* residualize ---------------------------
foreach Y in Y1 Y2 Z {
	reghdfe `Y', absorb(totfe) nocons resid 
	predict r`Y', resid 
}
replace rY1 = rY1 + `mu1'
replace rY2 = rY2 + `mu2'

* collapse to binscatter ------------------
binscatter rY1 rZ, nq(20) nodraw gen(bin)
collapse (mean) rY1 rY2 rZ, by(bin)

* build plot --------------------------
#delimit ;
twoway 
scatter rY1 rZ, mcolor(dknavy) msymbol(Oh) ||
lfit    rY1 rZ, lcolor(dknavy) lpattern(dash) ||
scatter rY2 rZ, mcolor(dkgreen) msymbol(Dh) ||
lfit    rY2 rZ, lcolor(dkgreen) lpattern(dash)
graphregion(color(white)) plotregion(lcolor(black) lwidth(medthin))
ylab(`ylo'(`yst')`yhi',nogrid) ytitle("Pr(Offense)")
xlab(-0.5(0.25)0.5,nogrid) xtitle("Officer Stringency")
legend(ring(0) pos(2) order(1 3) cols(1) region(lstyle(border))
lab(1 "Predicted Reoffending") lab(3 "Offense Past Year"))
text(`yt1' -0.45 "`b1'", place(e))
text(`yt2' -0.45 "`b2'", place(e)) ;
#delimit cr
graph export "${out}/main/validity_offending.pdf", replace
* -------------------------------------------------------------------------------------------


* full balance test -------------------------------------------------------------------------

* macros for balance test ------
#delimit ;
global cov = "female age agesq age_miss race_b race_h race_o race_u priorprison local
logzip zipincome_miss logprice veh_miss speed_py1 other_py1 crashany_py1" ;
#delimit cr

* setup data -------------------
use "${data}/out/4-main", clear
label var speed_py1 "Speeding Past Year"
label var other_py1 "Other Past Year"
label var crashany_py1 "Crash Past Year"
eststo clear 

* regression 1: recivism as outcome ---------
eststo: reghdfe cite_ny1 ${cov}, absorb(totfe) vce(cluster officerid)

test ${cov}
local f  = round(r(F),.01)
local p  = round(r(p),.0001)
local f1 = "F = `:di %6.2f r(F)'"
local p1 = "p = `:di %5.4f r(p)'"
if `p'==0 {
	local p  = "$<$.0001"
	local p1 = "p < 0.0001"
}
qui estadd local fstat `f'
qui estadd local pval `p'

summ cite_ny1 if e(sample)==1
local m = round(r(mean),.001)
qui estadd local mu `m'

egen X = group(officerid) if e(sample)==1
summ X
local noff = r(max)
qui estadd local ncluster `noff'
qui estadd local fe "Yes"
drop X 

* regression 2: not bunched as outcome --------------
eststo: reghdfe harsh ${cov}, absorb(totfe) vce(cluster officerid)

test ${cov}
local f  = round(r(F),.01)
local p  = round(r(p),.0001)
local f1 = "F = `:di %6.2f r(F)'"
local p1 = "p = `:di %5.4f r(p)'"
if `p'==0 {
	local p  = "$<$.0001"
	local p1 = "p < 0.0001"
}
qui estadd local fstat `f'
qui estadd local pval `p'

summ harsh if e(sample)==1
local m = round(r(mean),.001)
qui estadd local mu `m'

egen X = group(officerid) if e(sample)==1
summ X
local noff = r(max)
qui estadd local ncluster `noff'
qui estadd local fe "Yes"
drop X 

* regression 3: stringency as outcome -----------------
eststo: reghdfe Z ${cov}, absorb(totfe) vce(cluster officerid)

test ${cov}
local f  = round(r(F),.01)
local p  = round(r(p),.0001)
local f1 = "F = `:di %6.2f r(F)'"
local p1 = "p = `:di %5.4f r(p)'"
if `p'==0 {
	local p  = "$<$.0001"
	local p1 = "p < 0.0001"
}
qui estadd local fstat `f'
qui estadd local pval `p'

summ Z if e(sample)==1
local m = round(r(mean),.001)
qui estadd local mu `m'

egen X = group(officerid) if e(sample)==1
summ X
local noff = r(max)
qui estadd local ncluster `noff'
qui estadd local fe "Yes"
drop X 

* regression 4: 1[stringent] as outcome -------------------
gen harshpart = (lenientpart==0)
eststo: reghdfe harshpart ${cov}, absorb(totfe) vce(cluster officerid)

test ${cov}
local f  = round(r(F),.01)
local p  = round(r(p),.0001)
local f1 = "F = `:di %6.2f r(F)'"
local p1 = "p = `:di %5.4f r(p)'"
if `p'==0 {
	local p  = "$<$.0001"
	local p1 = "p < 0.0001"
}
qui estadd local fstat `f'
qui estadd local pval `p'

summ harshpart if e(sample)==1
local m = round(r(mean),.001)
qui estadd local mu `m'

egen X = group(officerid) if e(sample)==1
summ X
local noff = r(max)
qui estadd local ncluster `noff'
qui estadd local fe "Yes"
drop X 

* export LaTeX table ----------------------------------
#delimit ;
esttab using "${out}/apx_iv/table_balance.tex", nostar nogaps
drop(age_miss zipincome_miss veh_miss _cons) wrap varwidth(20) se 
stats(mu fstat pval fe ncluster N,
label("Mean" "F-Stat" "F-test" "Beat-Shift FE" "Officers" "Observations")) 
label fragment replace 
mtitles("Reoffend" "Harsh Fine" "Stringency" "$\mathbf{1}$[Stringent]") ;
#delimit cr
* -------------------------------------------------------------------------------------------



